﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace H2.NET.Controls
{
    public partial class GridView : Anthem.GridView
    {
        #region 属性 Public
        public ArrayList DynamicColumn = new ArrayList();
        public bool IsShowDelete
        {
            get
            {
                return ViewState[ID + "_gv_is_show_del"] == null ? false : (bool)ViewState[ID + "_gv_is_show_del"];
            }
            set
            {
                ViewState[ID + "_gv_is_show_del"] = value;
            }
        }

        public int ChangedRowIndex
        {
            get
            {
                return ViewState[ID + "_gv_row"] == null ? -1 : (int)ViewState[ID + "_gv_row"];
            }
            set
            {
                ViewState[ID + "_gv_row"] = value;
            }
        }

        public int ChangedColumnIndex
        {
            get
            {
                return ViewState[ID + "_gv_column"] == null ? -1 : (int)ViewState[ID + "_gv_column"];
            }
            set
            {
                ViewState[ID + "_gv_column"] = value;
            }
        }

        public string Key
        {
            get
            {
                return ViewState["Key"] == null ? "" : (string)ViewState["Key"];

            }
            set { ViewState["Key"] = value; }
        }

        private TaskStore StoreAPI
        {
            get
            {
                return ((TaskPage)Page).StoreAPI;
            }
        }
        #endregion

        #region 重载 DataSource
        /// <summary>
        /// 数据源
        /// </summary>
        public override object DataSource
        {
            get
            {
                if (string.IsNullOrEmpty(Key))
                {
                    return (object)ViewState["gv_ds_" + ID];
                }
                else
                {
                    return StoreAPI[Key + "~" + ID];
                }
            }
            set
            {
                if (string.IsNullOrEmpty(Key))
                {
                    ViewState["gv_ds_" + ID] = value;
                }
                else
                {
                    StoreAPI[Key + "~" + ID] = value;
                }
            }
        }
        #endregion

        #region 重载 OnLoad
        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            //注册 Ajax 回传
            Anthem.Manager.Register(this);
            Page.ClientScript.RegisterClientScriptBlock(
            typeof(GridView),
            "script",
            @"<script type='text/javascript'>
                function CellClick(GridView,Row,Column) 
                {
                    Anthem_InvokeControlMethod
                    (
                        GridView,
                        'OnCellClick',
                        [GridView,Row,Column],
                        function (result) 
                        {
                            try
                            {
                                if(result.value != null && result.value != '')
                                {
                                    document.getElementById(result.value).focus();
                                    document.getElementById(result.value).select();
                                }
                            }catch(exception)
                            {}
                        }
                    );
                }
              </script>");

            Columns.Clear();
            for (int i = 0; i < DynamicColumn.Count; i++)
            {
                TemplateField col = new TemplateField();

                //如果是绑定列的情况
                if (DynamicColumn[i] is BoundColumn2)
                {
                    BoundColumn2 bc = (BoundColumn2)DynamicColumn[i];
                    col.HeaderText = bc.Title;
                    col.HeaderStyle.HorizontalAlign = (HorizontalAlign)bc.Align;
                    col.HeaderTemplate = new BoundColumnTemplate(ListItemType.Header, bc);
                    col.ItemTemplate = new BoundColumnTemplate(ListItemType.Item, bc);
                    col.ItemStyle.HorizontalAlign = (HorizontalAlign)bc.Align;

                    //设置列宽
                    if (bc.Width > 0)
                    {
                        col.HeaderStyle.Width = bc.Width;
                    }
                    else if (bc.Width == 0)
                    {
                        col.Visible = false;
                    }
                }

                Columns.Add(col);
            }

            DataBind();
        }
        #endregion

        #region 重载 OnRowDataBound
        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnRowDataBound(GridViewRowEventArgs e)
        {
            base.OnRowDataBound(e);

            if (e.Row.RowType == DataControlRowType.DataRow && Enabled)
            {
                //为每个控件进行客户端事件注册
                for (int i = 0; i < e.Row.Cells.Count; i++)
                {
                    if (e.Row.Cells[i].Controls.Count >= 2)
                    {
                        e.Row.Cells[i].Attributes["onclick"] = "javascript:CellClick('" + this.ClientID + "','" + e.Row.RowIndex + "','" + i.ToString() + "');";
                        //e.Row.Cells[i].Attributes["onkeydown"] = "javascript:if(event.keyCode==40) {CellClick('" + this.ClientID + "','0','0');}";
                    }
                }
            }
        }
        #endregion

        #region 重载 OnRowUpdating
        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnRowUpdating(GridViewUpdateEventArgs e)
        {

            //Page.Response.Write(this.ClientID);
            if (e.RowIndex >= Rows.Count)
            {
                return;
            }

            if (ChangedColumnIndex != -1 && Enabled)
            {
                WebControl _editControl = (WebControl)Rows[e.RowIndex].Cells[ChangedColumnIndex].Controls[1];

                int _rowindex = e.RowIndex + (PageIndex * PageSize);

                //如果数据源是 Array 的情况
                if (DataSource is Array || DataSource is IList)
                {
                    object o = DataSource is Array ? ((Array)DataSource).GetValue(_rowindex) : ((IList)DataSource)[_rowindex];

                    System.Reflection.PropertyInfo[] pis = o.GetType().GetProperties();
                    foreach (System.Reflection.PropertyInfo pi in pis)
                    {
                        if (pi.Name.ToLower() == _editControl.Attributes["field"].ToLower())
                        {
                            object value = new object();

                            if (_editControl is Anthem.TextBox)
                            {
                                value = ((Anthem.TextBox)_editControl).Text;
                            }
                            else if (_editControl is H2.NET.Controls.Calendar)
                            {
                                value = ((H2.NET.Controls.Calendar)_editControl).Text;
                            }
                            else if (_editControl is Anthem.DropDownList)
                            {
                                value = ((Anthem.DropDownList)_editControl).SelectedValue;
                            }
                            else if (_editControl is Anthem.CheckBox)
                            {
                                value = ((Anthem.CheckBox)_editControl).Checked;
                            }

                            try
                            {
                                pi.SetValue(o, value, null);
                            }
                            catch (Exception ex)
                            {
                                throw (new Exception("绑定字段与实现输入数据格式不一致，请检查输入是否正确！" + ex.Message));
                            }
                            break;
                        }
                    }
                }
                //如果数据类型是 DataTable 的情况
                else if (DataSource is DataTable)
                {
                    DataTable dt = (DataTable)DataSource;

                    DataRow dr = dt.Rows[_rowindex];
                    dr.BeginEdit();

                    if (_editControl is Anthem.TextBox)
                    {
                        dr[_editControl.Attributes["field"]] = ((Anthem.TextBox)_editControl).Text;
                    }
                    else if (_editControl is H2.NET.Controls.Calendar)
                    {
                        dr[_editControl.Attributes["field"]] = ((H2.NET.Controls.Calendar)_editControl).Text;
                    }
                    else if (_editControl is Anthem.DropDownList)
                    {
                        dr[_editControl.Attributes["field"]] = ((Anthem.DropDownList)_editControl).SelectedValue;
                    }
                    else if (_editControl is Anthem.CheckBox)
                    {
                        dr[_editControl.Attributes["field"]] = ((Anthem.CheckBox)_editControl).Checked;
                    }

                    dr.EndEdit();

                    //保存更新后的 DataTable
                    DataSource = dt;
                }

                //重新更新后数据源
                DataBind();
            }
        }
        #endregion

        #region 单击 CellClick
        [Anthem.Method]
        public string OnCellClick(string GridViewID, string Row, string Column)
        {
            //取得行位置
            int _rowIndex = int.Parse(Row);

            //解析 Event Argument，以取得列标识(此信息在 RowDataBound 中进行的数据填充)
            int _columnIndex = int.Parse(Column);

            if (ChangedRowIndex != -1)
            {
                UpdateRow(ChangedRowIndex, false);
            }

            ChangedRowIndex = _rowIndex;
            ChangedColumnIndex = _columnIndex;

            TableCell Cell = Rows[_rowIndex].Cells[_columnIndex];
            Cell.Controls[0].Visible = false;
            Cell.Controls[1].Visible = true;

            //取消此单元格的客户端 onclick 事件
            Cell.Attributes.Clear();

            //如果此编辑控件是 DropDownList，则进行初始值设置
            if (Cell.Controls[1] is Anthem.DropDownList && Cell.Controls[0] is Anthem.Label)
            {
                Anthem.DropDownList drp = (Anthem.DropDownList)Cell.Controls[1];
                drp.SelectedIndex = -1;
                string value = ((Anthem.Label)Cell.Controls[0]).Text;
                foreach (ListItem li in drp.Items)
                {
                    if (li.Value == value)
                    {
                        li.Selected = true;
                        break;
                    }
                }
            }

            //如果此编辑控件是 CheckBox，则进行初始值设置
            if (Cell.Controls[1] is Anthem.CheckBox)
            {
                bool value = false;
                bool.TryParse(((Anthem.Label)Cell.Controls[0]).Text, out  value);
                ((Anthem.CheckBox)Cell.Controls[1]).Checked = value;
            }

            //补充焦点离开的事件
            if (((WebControl)Cell.Controls[1]).Attributes["ct-type"] == "TextBox"
                        || ((WebControl)Cell.Controls[1]).Attributes["ct-type"] == "Calender")
            {
                return Rows[_rowIndex].Cells[_columnIndex].Controls[1].ClientID;
            }
            else
            {
                return "";
            }


        }
        #endregion
    }

    #region 模板列 BoundColumnTemplate
    /// <summary>
    /// 
    /// </summary>
    public class BoundColumnTemplate : ITemplate
    {
        ListItemType ListItemType;
        BoundColumn2 Column;

        public BoundColumnTemplate(ListItemType ListItemType, BoundColumn2 Column)
        {
            this.ListItemType = ListItemType;
            this.Column = Column;
        }

        #region 方法 InstantiateIn
        /// <summary>
        /// 
        /// </summary>
        /// <param name="container"></param>
        public void InstantiateIn(Control container)
        {
            switch (ListItemType)
            {
                case ListItemType.Header:
                    Anthem.Label Head = new Anthem.Label();
                    Head.Text = Column.Title;
                    container.Controls.Add(Head);
                    break;

                case ListItemType.Item:

                    //如果是显示控件的情况
                    WebControl dc = null;
                    switch (Column.BoundColumnType)
                    {
                        case BoundColumnType2.Image:
                            dc = new Anthem.Image();
                            ((Anthem.Image)dc).Attributes["ct-type"] = "Image";
                            break;
                        case BoundColumnType2.Button:
                            dc = new Anthem.Button();
                            ((Anthem.Button)dc).Attributes["ct-type"] = "Button";
                            break;
                        default:
                            dc = new Anthem.Label();
                            ((Anthem.Label)dc).Attributes["ct-type"] = "Label";
                            break;
                    }

                    //将显示控件加入容器
                    if (dc != null)
                    {
                        dc.ID = "dc" + Column.ID;
                        dc.CssClass = "dc";
                        dc.DataBinding += new EventHandler(OnCellDataBinding);
                        container.Controls.Add(dc);
                    }

                    //如果此列被禁用，则不用创建编辑项
                    if (!Column.Enable)
                    {
                        break;
                    }

                    //如果是编辑控件的情况
                    WebControl ec = null;
                    switch (Column.BoundColumnType)
                    {
                        case BoundColumnType2.TextBox:
                            ec = new Anthem.TextBox();
                            ((Anthem.TextBox)ec).EnableCallBack = true;
                            ((Anthem.TextBox)ec).AutoUpdateAfterCallBack = true;
                            ((Anthem.TextBox)ec).Attributes["ct-type"] = "TextBox";
                            //如果是数字类型，则增加 onkeypress 控制
                            if (Column.InputType == InputType.Numeric)
                            {
                                ((Anthem.TextBox)ec).Attributes["onkeypress"] = "if(String.fromCharCode(event.keyCode).search(/^[0-9-.]$/) == -1){return false;}";
                            }

                            break;
                        case BoundColumnType2.Calender:
                            ec = new H2.NET.Controls.Calendar();
                            ((H2.NET.Controls.Calendar)ec).EnableCallBack = true;
                            ((H2.NET.Controls.Calendar)ec).AutoUpdateAfterCallBack = true;
                            ((H2.NET.Controls.Calendar)ec).Attributes["ct-type"] = "Calender";
                            break;
                        case BoundColumnType2.LinkButton:
                            ec = new Anthem.LinkButton();
                            ((Anthem.LinkButton)ec).Attributes["ct-type"] = "LinkButton";
                            break;
                        case BoundColumnType2.CheckBox:
                            ec = new Anthem.CheckBox();
                            ((Anthem.CheckBox)ec).EnableCallBack = true;
                            ((Anthem.CheckBox)ec).AutoUpdateAfterCallBack = true;
                            ((Anthem.CheckBox)ec).Attributes["ct-type"] = "CheckBox";
                            break;
                        case BoundColumnType2.DropDownList:
                            ec = new Anthem.DropDownList();
                            ((Anthem.DropDownList)ec).EnableCallBack = true;
                            ((Anthem.DropDownList)ec).AutoUpdateAfterCallBack = true;
                            ((Anthem.DropDownList)ec).Attributes["ct-type"] = "DropDownList";
                            break;
                    }

                    //如果在列表里存在时
                    if (ec != null)
                    {
                        ec.ID = "ec" + Column.ID;
                        ec.CssClass = "ec";
                        ec.Visible = false;
                        ec.DataBinding += new EventHandler(OnCellDataBinding);     
                        container.Controls.Add(ec);
                    }
                    break;

                case ListItemType.EditItem:
                    break;

                case ListItemType.Footer:
                    break;
            }
        }
        #endregion

        #region 方法 OnCellDataBinding
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnCellDataBinding(object sender, EventArgs e)
        {
            object value;

            //绑定填充值
            switch (sender.GetType().Name)
            {
                case "Label":
                    Anthem.Label Label = (Anthem.Label)sender;
                    value = DataBinder.Eval(((GridViewRow)(Label).NamingContainer).DataItem, Column.Field);
                    Label.Text = value == null ? "" : value.ToString();
                    Label.Attributes["field"] = Column.Field;
                    Label.BackColor = Column.Enable || Column.ID == "ID" ? System.Drawing.Color.White : System.Drawing.Color.FromArgb(237, 237, 237);
                    //Label.Height = Column.Enable && Column.ID == "ID" ? 18 : 1;
                    break;

                case "TextBox":
                    Anthem.TextBox TextBox = (Anthem.TextBox)sender;
                    value = DataBinder.Eval(((GridViewRow)(TextBox).NamingContainer).DataItem, Column.Field);
                    TextBox.Text = value == null ? "" : value.ToString();
                    TextBox.Attributes["field"] = Column.Field;
                    break;

                case "Calendar":
                    H2.NET.Controls.Calendar Calendar = (H2.NET.Controls.Calendar)sender;
                    value = DataBinder.Eval(((GridViewRow)(Calendar).NamingContainer).DataItem, Column.Field);
                    Calendar.Text = value == null ? "" : value.ToString();
                    Calendar.Attributes["field"] = Column.Field;
                    break;

                case "CheckBox":
                    Anthem.CheckBox CheckBox = (Anthem.CheckBox)sender;
                    value = DataBinder.Eval(((GridViewRow)(CheckBox).NamingContainer).DataItem, Column.Field);
                    bool value2 = false;
                    bool.TryParse(value == null ? "" : value.ToString(), out value2);
                    CheckBox.Checked = value2;
                    CheckBox.Attributes["field"] = Column.Field;
                    break;

                case "DropDownList":
                    Anthem.DropDownList DropDownList = (Anthem.DropDownList)sender;
                    value = DataBinder.Eval(((GridViewRow)(DropDownList).NamingContainer).DataItem, Column.Field);
                    DropDownList.Attributes["field"] = Column.Field;
                    DropDownList.DataSource = Column.DataSource;
                    break;

                case "Button":
                    Anthem.Button Button = (Anthem.Button)sender;
                    if (!string.IsNullOrEmpty(Column.Field))
                    {
                        value = DataBinder.Eval(((GridViewRow)(Button).NamingContainer).DataItem, Column.Field);
                        Button.Text = value == null ? "" : value.ToString();
                    }
                    Button.Attributes["field"] = Column.Field;
                    break;

                case "LinkButton":
                    Anthem.LinkButton LinkButton = (Anthem.LinkButton)sender;
                    if (!string.IsNullOrEmpty(Column.Field))
                    {
                        value = DataBinder.Eval(((GridViewRow)(LinkButton).NamingContainer).DataItem, Column.Field);
                        LinkButton.Text = value == null ? "" : value.ToString();
                    }
                    LinkButton.Attributes["field"] = Column.Field;
                    break;

                case "Image":
                    Anthem.Image Image = (Anthem.Image)sender;
                    value = DataBinder.Eval(((GridViewRow)(Image).NamingContainer).DataItem, Column.Field);
                    ((Anthem.Image)sender).ImageUrl = value == null ? "" : value.ToString();
                    Image.Attributes["field"] = Column.Field;
                    break;
            }
        }
        #endregion
    }
    #endregion

    #region 模板列 BoundColumn
    [Serializable]
    public partial class BoundColumn2
    {
        public string ID { get; set; }                          //ID
        public string Title { get; set; }                       //名称(标题)
        public BoundColumnType2 BoundColumnType { get; set; }    //类型
        public int Width { get; set; }                          //宽度
        public Align Align { get; set; }                        //对齐方式
        public bool Enable { get; set; }                        //是否只读
        public string Field { get; set; }                       //绑定字段
        public InputType InputType { get; set; }                //输入控制
        public object DataSource { get; set; }                  //数据源

        public BoundColumn2(string ID, string Title, BoundColumnType2 BoundColumnType, int Width, Align Align, bool Enable, string Field, InputType InputType, object DataSource)
        {
            this.ID = ID;
            this.Title = Title;
            this.BoundColumnType = BoundColumnType;
            this.Width = Width;
            this.Align = Align;
            this.Enable = Enable;
            this.Field = Field;
            this.InputType = InputType;
            this.DataSource = DataSource;
        }
    }

    public enum BoundColumnType2
    {
        Label,
        TextBox,
        CheckBox,
        DropDownList,
        Button,
        LinkButton,
        Image,
        ImageButton,
        Calender
    }

    public enum Align
    {
        NotSet = 0,     //未设置水平对齐方式。
        Left = 1,       //容器的内容左对齐。
        Center = 2,     //容器的内容居中。
        Right = 3,      //容器的内容右对齐。
        Justify = 4     //容器的内容均匀展开，与左右边距对齐。
    }

    public enum InputType
    {
        None = 0,
        Numeric = 1,
        Alphabetic = 2,
        UpperCase = 3,
        LowerCase = 4,
        Mask = 5 
    }
    #endregion
}
